package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.config.exception.LoginException;
import org.example.config.exception.RegisterException;
import org.example.config.UserContextHolder;
import org.example.dao.entity.UserEntity;
import org.example.dao.entity.UserRoleEntity;
import org.example.dao.entity.UserSocialEntity;
import org.example.dao.mapper.UserMapper;
import org.example.dao.mapper.UserRoleMapper;
import org.example.dao.mapper.UserSocialMapper;
import org.example.service.UserService;
import org.example.utils.JwtUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.client.RestTemplate;

import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final TransactionTemplate transactionTemplate;
    private final StringRedisTemplate stringRedisTemplate;
    private final UserSocialMapper userSocialMapper;

    @Override
    public String socialLogin() {
        return null;
    }

    @Override
    public UserSocialEntity getUserInfo(String accessToken) {
        try {
            // 设置请求头，添加 Authorization 字段（Bearer 令牌）
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Bearer " + accessToken);
            headers.add("Accept", "application/json");
            // 创建 HTTP 请求
            HttpEntity<?> request2 = new HttpEntity<>(headers);

            // 发送 GET 请求到 GitHub 用户信息 API
            RestTemplate restTemplate = new RestTemplate();
            String GITHUB_USER_URL = "https://api.github.com/user";
            ResponseEntity<String> response2 = restTemplate.exchange(
                    GITHUB_USER_URL,
                    HttpMethod.GET,
                    request2,
                    String.class
            );

            if (response2.getStatusCode() == HttpStatus.OK) {
                ObjectMapper mapper2 = new ObjectMapper();
                HashMap<String, Object> map = mapper2.readValue(response2.getBody(), HashMap.class);

                Integer id = (Integer) map.get("id");

                String nodeId = (String) map.get("node_id");
                String name = (String) map.get("login");
                UserSocialEntity userSocialEntity = userSocialMapper.selectOne(Wrappers.lambdaQuery(UserSocialEntity.class).eq(UserSocialEntity::getId, id));
                if (userSocialEntity == null) {
                    // 添加用户
                    UserEntity userEntity = new UserEntity();
                    userEntity.setUsername(name);
                    userMapper.insert(userEntity);

                    userSocialEntity = new UserSocialEntity();

                    userSocialEntity.setId(id);
                    userSocialEntity.setUserId(userEntity.getId());
                    userSocialEntity.setPlatformId(0);
                    userSocialEntity.setName(name);
                    userSocialEntity.setNodeId(nodeId);
                    userSocialMapper.insert(userSocialEntity);
                }
                return userSocialEntity;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    // TODO 异地登录，强制下线
    // prefix + userId, token
    @Override
    public String userLogin(String username, String password) {
        if (username == null || username.isEmpty()) throw new LoginException("用户名不能为空");
        LambdaQueryWrapper<UserEntity> eq = Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUsername, username);
        UserEntity userEntity = userMapper.selectOne(eq);
        if (userEntity == null) throw new LoginException("用户不存在");
        if (!password.equals(userEntity.getPassword())) throw new LoginException("密码错误");

        String token = JwtUtil.generateToken(username);
        stringRedisTemplate.opsForValue().set(username, token, 30, TimeUnit.MINUTES);
        return "success: " + token;
    }

    @Override
    public void register(String username, String password) {
        if (username == null || username.length() < 6 || username.length() > 18) throw new RegisterException("用户名长度不在6~18范围内");
        if (password == null || password.length() > 18 || password.length() < 8) throw new RegisterException("密码长度不在6~18范围内");
        LambdaQueryWrapper<UserEntity> eq = Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUsername, username);

        if (userMapper.selectOne(eq) != null) {
            throw new RegisterException("用户名已存在");
        }

        transactionTemplate.execute(status -> {
            try {
                UserEntity userEntity = new UserEntity();
                userEntity.setUsername(username);
                userEntity.setPassword(password);
                userMapper.insert(userEntity);

                userRoleMapper.insert(new UserRoleEntity(userEntity.getId(), "default"));
            } catch (Exception e) {
                status.setRollbackOnly();
            }
            return null;
        });
        log.info("注册成功");
    }

    @Override
    public String loginWithToken(String token) {
        String username = JwtUtil.getUsernameFromToken(token);

        String s = stringRedisTemplate.opsForValue().get(username);
        if (s == null || s.isEmpty()) return "登录失败";

        UserEntity userEntity = userMapper.selectOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUsername, username));
        if (userEntity == null) return null;
        return "登录成功";
    }

    @Override
    public String logout() {
        Map<String, String> map = UserContextHolder.get();
        String token = map.get("token");
        stringRedisTemplate.delete(token);
        return "退出登录";
    }

    @Override
    public String revoked() {
        Map<String, String> map = UserContextHolder.get();
        String username = map.get("username");

        userMapper.delete(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUsername, username));

        return "注销成功";
    }
}
